﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace PatcherYRpp
{
    [StructLayout(LayoutKind.Explicit, Size = 90296)]
    public struct HouseClass
    {
        private static IntPtr arrayPoint = new IntPtr(0xA80228);
        public static ref DynamicVectorClass<Pointer<HouseClass>> Array { get => ref DynamicVectorClass<Pointer<HouseClass>>.GetDynamicVector(arrayPoint); }

        public static Pointer<HouseClass> Player { get => player.Convert<Pointer<HouseClass>>().Data; set => player.Convert<Pointer<HouseClass>>().Ref = value; }
        private static IntPtr player = new IntPtr(0xA83D4C);
        public static Pointer<HouseClass> Observer { get => observer.Convert<Pointer<HouseClass>>().Data; set => observer.Convert<Pointer<HouseClass>>().Ref = value; }
        private static IntPtr observer = new IntPtr(0xAC1198);


        [FieldOffset(48)]
        public int ArrayIndex;

        [FieldOffset(52)]
        public Pointer<HouseTypeClass> Type;


        [FieldOffset(80)] public byte conyards;
        public ref DynamicVectorClass<Pointer<BuildingClass>> ConYards => ref Pointer<byte>.AsPointer(ref conyards).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(104)] public byte buildings;
        public ref DynamicVectorClass<Pointer<BuildingClass>> Buildings => ref Pointer<byte>.AsPointer(ref buildings).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(128)] public byte unitRepairStations;
        public ref DynamicVectorClass<Pointer<BuildingClass>> UnitRepairStations => ref Pointer<byte>.AsPointer(ref unitRepairStations).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(152)] public byte grinders;
        public ref DynamicVectorClass<Pointer<BuildingClass>> Grinders => ref Pointer<byte>.AsPointer(ref grinders).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(176)] public byte absorbers;
        public ref DynamicVectorClass<Pointer<BuildingClass>> Absorbers => ref Pointer<byte>.AsPointer(ref absorbers).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(200)] public byte bunkers;
        public ref DynamicVectorClass<Pointer<BuildingClass>> Bunkers => ref Pointer<byte>.AsPointer(ref bunkers).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(224)] public byte occupiables;
        public ref DynamicVectorClass<Pointer<BuildingClass>> Occupiables => ref Pointer<byte>.AsPointer(ref occupiables).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(248)] public byte cloningVats;
        public ref DynamicVectorClass<Pointer<BuildingClass>> CloningVats => ref Pointer<byte>.AsPointer(ref cloningVats).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(272)] public byte secretLabs;
        public ref DynamicVectorClass<Pointer<BuildingClass>> SecretLabs => ref Pointer<byte>.AsPointer(ref secretLabs).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(296)] public byte psychicDetectionBuildings;
        public ref DynamicVectorClass<Pointer<BuildingClass>> PsychicDetectionBuildings => ref Pointer<byte>.AsPointer(ref psychicDetectionBuildings).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(320)] public byte factoryPlants;
        public ref DynamicVectorClass<Pointer<BuildingClass>> FactoryPlants => ref Pointer<byte>.AsPointer(ref factoryPlants).Convert<DynamicVectorClass<Pointer<BuildingClass>>>().Ref;

        [FieldOffset(392)] public double FirepowerMultiplier;

        [FieldOffset(400)] public double GroundspeedMultiplier;

        [FieldOffset(408)] public double AirspeedMultiplier;

        [FieldOffset(416)] public double ArmorMultiplier;

        [FieldOffset(424)] public double ROFMultiplier;

        [FieldOffset(432)] public double CostMultiplier;

        [FieldOffset(440)] public double BuildTimeMultiplier;




        public Pointer<SuperClass> FindSuperWeapon(Pointer<SuperWeaponTypeClass> pType)
        {
            for (int i = 0; i < Supers.Count; i++)
            {
                var pItem = Supers[i];
                if(pItem.Ref.Type == pType)
                {
                    return pItem;
                }
            }

            return Pointer<SuperClass>.Zero;
        }


        public unsafe Bool IsAlliedWith(int idxHouse)
        {
            var func = (delegate* unmanaged[Thiscall]<IntPtr, int, Bool>)0x4F9A10;
            return func(Pointer<HouseClass>.AsPointer(ref this), idxHouse);
        }

        public unsafe Bool IsAlliedWith(Pointer<HouseClass> house)
        {
            return IsAlliedWith(house.Ref.ArrayIndex);
        }

        public unsafe Bool ControlledByHuman()
        {
            Bool result = CurrentPlayer;
            return result;
        }
        public unsafe Bool ControlledByPlayer()
        {
            Bool result = CurrentPlayer || PlayerControl;
            return result;
        }



        public unsafe void TakeMoney(int amount)
        {
            var func = (delegate* unmanaged[Thiscall]<IntPtr, int, void>)0x4F9790;
            func(Pointer<HouseClass>.AsPointer(ref this), amount);
        }

        public unsafe void GiveMoney(int amount)
        {
            var func = (delegate* unmanaged[Thiscall]<IntPtr, int, void>)0x4F9950;
            func(Pointer<HouseClass>.AsPointer(ref this), amount);
        }


        //bool CanTransactMoney(int amount) const {
        //return amount > 0 || this->Available_Money() >= -amount;
        //}

        public void TransactMoney(int amount)
        {
            if (amount > 0)
            {
                GiveMoney(amount);
            }
            else
            {
                TakeMoney(-amount);
            }
        }




        [FieldOffset(492)] public Bool CurrentPlayer;

        [FieldOffset(493)] public Bool PlayerControl;

        [FieldOffset(501)] public Bool Defeated;

        [FieldOffset(502)] public Bool IsGameOver;

        [FieldOffset(503)] public Bool IsWinner;

        [FieldOffset(504)] public Bool IsLoser;

        [FieldOffset(596)]
        public DynamicVectorClass<Pointer<SuperClass>> Supers;

        [FieldOffset(21556)]
        public int TotalKilledUnits;
        [FieldOffset(21640)]
        public int TotalKilledBuildings;
        [FieldOffset(21736)]
        public int SiloMoney;

        [FieldOffset(22265)] public ColorStruct Color;

        [FieldOffset(22268)] public ColorStruct LaserColor;


    }
}
